home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume8 / mcp / part06 < prev    next >
Encoding:
Internet Message Format  |  1987-02-05  |  53.7 KB

  1. Subject:  v08i046:  Account creation/manipulation program, Part06/08
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: Kyle Jones <xanth!kyle>
  6. Mod.sources: Volume 8, Issue 46
  7. Archive-name: mcp/Part06
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If all goes well, you will see the message "End of archive 6 (of 8)."
  13. # Contents:  src/gpa.c src/init.c src/job.c src/lastlog.c src/list.c
  14. #   src/lists.c src/macros.h src/mem.c src/mem.h MANIFEST
  15. # Wrapped by rs@mirror on Fri Feb  6 15:56:07 1987
  16. PATH=/bin:/usr/bin:/usr/ucb; export PATH
  17. echo shar: extracting "'src/gpa.c'" '(2500 characters)'
  18. if test -f 'src/gpa.c' ; then 
  19.   echo shar: will not over-write existing file "'src/gpa.c'"
  20. else
  21. sed 's/^X//' >src/gpa.c <<'@//E*O*F src/gpa.c//'
  22. X/***************************************************************************\
  23. X*                                         *
  24. X*     gpa.c                                    *
  25. X*                                         *
  26. X* These are the support routines for the global_pointer_array that all        *
  27. X* routines that get input from the tty use, excluding main().            *
  28. X*                                         *
  29. X* Routines needing an argv like array to store pointers call get_gpa()        *
  30. X* which returns a pointer to chunk of the global_pointer_array of the        *
  31. X* requested size.  Such a central array is needed to insure that all        *
  32. X* allocations via savestr() in get_line() are freed by a call to        *
  33. X* free_gpa().  This is insured even from interrupts by always calling        *
  34. X* free_gpa() in main() before getting the next command line.            *
  35. X*                                         *
  36. X* clear_gpa() is used by routines that already have made a call to        *
  37. X* get_gpa() and want to reuse the space provided, but need to be sure that  *
  38. X* any leftover pointers freed before they are overwritten.            *
  39. X*                                         *
  40. X* ----------                                    *
  41. X*                                         *
  42. X* get_gpa()    get a chunk of the global_pointer_array                *
  43. X*                                         *
  44. X* clear_gpa()    free the pointers stored in a certian part            *
  45. X*         of the array for reuse.                        *
  46. X*                                         *
  47. X* free_gpa()    free all pointers in the global_pointer_array            *
  48. X*         and reset the array index to zero.                *
  49. X*                                         *
  50. X* pop_gpa()    used to free last allocated part of the                *
  51. X*         global_pointer_array.  Designed for use by routines        *
  52. X*         in yesno.c.  No other routines should need call this.        *
  53. X*                                         *
  54. X\***************************************************************************/
  55. X
  56. X#include "sysdep.h"
  57. X#include "mem.h"
  58. X#include "gpa.h"
  59. X
  60. Xstatic    addr global_pointer_array[G_P_A__SIZE];
  61. Xstatic    int gpaindex;
  62. X
  63. Xaddr *
  64. Xget_gpa(n)
  65. Xint n;
  66. X
  67. X{
  68. X    gpaindex += n;
  69. X    return &global_pointer_array[gpaindex-n];
  70. X}
  71. X
  72. Xfree_gpa()
  73. X
  74. X{
  75. X    int i;
  76. X
  77. X    critical();
  78. X    for (i=0; i<G_P_A__SIZE; i++)
  79. X        if (global_pointer_array[i]) {
  80. X            FREEMEM((char *)global_pointer_array[i]);
  81. X            global_pointer_array[i] = NIL;
  82. X        }
  83. X    gpaindex = 0;
  84. X    non_critical();
  85. X    return;
  86. X}
  87. X
  88. Xint clear_gpa(p, n)
  89. Xaddr *p;
  90. Xint n;
  91. X
  92. X{
  93. X    register int i;
  94. X
  95. X    for (i=0; i<n; i++)
  96. X        if (p[i]) {
  97. X            /*
  98. X             * Can't let user interrupt between the FREEMEM
  99. X             * and zeroing the pointer.
  100. X             */
  101. X            critical();
  102. X            FREEMEM((char *)p[i]);
  103. X            p[i] = NIL;
  104. X            non_critical();
  105. X        }
  106. X    return 1;    /* used as do-while constant */
  107. X}
  108. X
  109. Xpop_gpa(n)
  110. Xint n;
  111. X
  112. X{
  113. X    (void) clear_gpa(&global_pointer_array[gpaindex-n], n);
  114. X    gpaindex -= n;
  115. X    return;
  116. X}
  117. @//E*O*F src/gpa.c//
  118. if test 2500 -ne "`wc -c <'src/gpa.c'`"; then
  119.     echo shar: error transmitting "'src/gpa.c'" '(should have been 2500 characters)'
  120. fi
  121. fi # end of overwriting check
  122. echo shar: extracting "'src/init.c'" '(16005 characters)'
  123. if test -f 'src/init.c' ; then 
  124.   echo shar: will not over-write existing file "'src/init.c'"
  125. else
  126. sed 's/^X//' >src/init.c <<'@//E*O*F src/init.c//'
  127. X#include <stdio.h>
  128. X#include <sys/file.h>
  129. X#include <sys/types.h>
  130. X#include <pwd.h>
  131. X#include <grp.h>
  132. X#include <lastlog.h>
  133. X#include <strings.h>
  134. X#include <errno.h>
  135. X#include "sysdep.h"
  136. X#include "macros.h"
  137. X#include "mem.h"
  138. X#include "sort.h"
  139. X#include "lists.h"
  140. X#include "save.h"
  141. X#include "sig.h"
  142. X#include "class.h"
  143. X#include "account.h"
  144. X#include "command.h"
  145. X#include "groupmap.h"
  146. X#include "range.h"
  147. X#ifdef SENDMAIL
  148. X#include "alias.h"
  149. X#endif
  150. X
  151. X#ifdef sun
  152. X# ifdef DOFILES
  153. X/*
  154. X * Lint complains about all the unused functions declared in netdb.h
  155. X * and mntent.h... but these functions are >>declared<< NOT
  156. X * >>defined<< so lint should SHUT UP about this!!  Since it doesn't, 
  157. X * we work around its ignorance.
  158. X */
  159. X#  ifndef lint
  160. X#  include <mntent.h>
  161. X#  include <netdb.h>
  162. X#  else
  163. Xstruct    servent {
  164. X    char    *s_name;    /* official service name */
  165. X    char    **s_aliases;    /* alias list */
  166. X    int    s_port;        /* port # */
  167. X    char    *s_proto;    /* protocol to use */
  168. X};
  169. Xstruct    servent *getservbyname();
  170. X
  171. X#  define MNTTAB    "/etc/fstab"
  172. Xstruct    mntent{
  173. X    char    *mnt_fsname;        /* name of mounted file system */
  174. X    char    *mnt_dir;        /* file system path prefix */
  175. X    char    *mnt_type;        /* MNTTYPE_* */
  176. X    char    *mnt_opts;        /* MNTOPT* */
  177. X    int    mnt_freq;        /* dump frequency, in days */
  178. X    int    mnt_passno;        /* pass number on parallel fsck */
  179. X};
  180. Xstruct    mntent *getmntent();
  181. XFILE     *setmntent();
  182. X#  endif lint
  183. X# endif DOFILES
  184. X#endif sun
  185. X
  186. Xstatic char *e1 = "password file has more lines than accounts file.";
  187. Xstatic char *e2 = "accounts file has more lines than password file.";
  188. Xstatic char *e3 = "line %d: login name not the same in accounts/passwd.";
  189. X
  190. Xextern    struct lastlog *getlluid(), *getllent();
  191. Xextern    struct list YesNo, Titles, Suffixes, History;
  192. Xextern    char *sprintf(), *getpass();
  193. X
  194. X#ifdef BSD4_3
  195. Xuid_t    geteuid(), getuid();
  196. Xchar    *getwd();
  197. Xtime_t    time();
  198. X#endif
  199. X
  200. X#ifdef SENDMAIL
  201. Xextern    addalias(), addtoalias(), bindclass(), bindgroup(), bindsig();
  202. Xextern    desalias();
  203. Xextern    rmalias(), rmfromalias(), ubindclass(), ubindgroup(), ubindsig();
  204. Xextern    updalias();
  205. X#endif
  206. X#ifdef HELPDIR
  207. Xextern    descommand(), whatis();
  208. X#endif
  209. Xextern    addclass(), addgroup(), addrange(), addsig();
  210. Xextern    addtoclass(), addtogroup();
  211. Xextern    addtosig(), adduser(), addvig();
  212. Xextern    ckpchanges();
  213. Xextern    deschanges(), desclass();
  214. Xextern    descryos(), desdeadbeats(), desgroup(), desinactives(), desrange();
  215. Xextern    dessig(), desuser(), disableuser(), exitmcp();
  216. Xextern    freezedeadbeats(), freezeinactives(), freezeuser();
  217. Xextern    listgeneric(), listcryos();
  218. Xextern    listdeadbeats(), listinactives();
  219. Xextern    loadfile(), pausemcp(), rmclass();
  220. Xextern    rmcryos(), rmfromclass(), rmfromgroup(), rmfromsig();
  221. Xextern    rmgroup();
  222. Xextern    rmrange(), rmsig(), rmuser(), rmvig(), savechanges(), saveandexit();
  223. Xextern    shellescape();
  224. Xextern    updclass(), updgroup(), updrange(), updsig(), upduser();
  225. X
  226. Xstruct command Ctable[] = {
  227. X#ifdef SENDMAIL
  228. X    { "add-alias",        addalias,        1 },
  229. X#endif
  230. X    { "add-class",        addclass,        1 },
  231. X    { "add-group",        addgroup,        1 },
  232. X    { "add-range",        addrange,        1 },
  233. X    { "add-sig",        addsig,            1 },
  234. X#ifdef SENDMAIL
  235. X    { "add-to-alias",    addtoalias,        1 },
  236. X#endif
  237. X    { "add-to-class",    addtoclass,        1 },
  238. X    { "add-to-group",    addtogroup,        1 },
  239. X    { "add-to-sig",        addtosig,        1 },
  240. X    { "add-user",        adduser,        1 },
  241. X    { "add-vig",        addvig,            1 },
  242. X#ifdef SENDMAIL
  243. X    { "bind-group",        bindgroup,        1 },
  244. X    { "bind-class",        bindclass,        1 },
  245. X    { "bind-sig",        bindsig,        1 },
  246. X#endif
  247. X    { "checkpoint-changes",    ckpchanges,        1 },
  248. X#ifdef SENDMAIL
  249. X    { "describe-alias",    desalias,        0 },
  250. X#endif
  251. X    { "describe-class",    desclass,        0 },
  252. X    { "describe-changes",    deschanges,        1 },
  253. X#ifdef HELPDIR
  254. X    { "describe-command",    descommand,        0 },
  255. X#endif
  256. X    { "describe-cryos",    descryos,        0 },
  257. X    { "describe-deadbeats",    desdeadbeats,        0 },
  258. X    { "describe-group",    desgroup,        0 },
  259. X    { "describe-inactives",    desinactives,        0 },
  260. X    { "describe-range",    desrange,        0 },
  261. X    { "describe-sig",    dessig,            0 },
  262. X    { "describe-user",    desuser,        0 },
  263. X    { "disable-user",    disableuser,        1 },
  264. X    { "exit-mcp",        exitmcp,        0 },
  265. X    { "freeze-deadbeats",    freezedeadbeats,    1 },
  266. X    { "freeze-inactives",    freezeinactives,    1 },
  267. X    { "freeze-user",    freezeuser,        1 },
  268. X#ifdef SENDMAIL
  269. X    { "list-aliases",    listgeneric,        0 },
  270. X#endif
  271. X    { "list-classes",    listgeneric,        0 },
  272. X    { "list-commands",    listgeneric,        0 },
  273. X    { "list-cryos",        listcryos,        0 },
  274. X    { "list-deadbeats",    listdeadbeats,        0 },
  275. X    { "list-groups",    listgeneric,        0 },
  276. X    { "list-inactives",    listinactives,        0 },
  277. X    { "list-ranges",    listgeneric,        0 },
  278. X    { "list-sigs",        listgeneric,        0 },
  279. X    { "list-users",        listgeneric,        0 },
  280. X    { "list-vigs",        listgeneric,        0 },
  281. X    { "load-file",        loadfile,        1 },
  282. X    { "pause-mcp",        pausemcp,        0 },
  283. X#ifdef SENDMAIL
  284. X    { "remove-alias",    rmalias,        1 },
  285. X#endif
  286. X    { "remove-class",    rmclass,        1 },
  287. X    { "remove-cryos",    rmcryos,        1 },
  288. X#ifdef SENDMAIL
  289. X    { "remove-from-alias",    rmfromalias,        1 },
  290. X#endif
  291. X    { "remove-from-class",    rmfromclass,        1 },
  292. X    { "remove-from-group",    rmfromgroup,        1 },
  293. X    { "remove-from-sig",    rmfromsig,        1 },
  294. X    { "remove-group",    rmgroup,        1 },
  295. X    { "remove-range",    rmrange,        1 },
  296. X    { "remove-sig",        rmsig,            1 },
  297. X    { "remove-user",    rmuser,            1 },
  298. X    { "remove-vig",        rmvig,            1 },
  299. X    { "save-and-exit",    saveandexit,        1 },
  300. X    { "save-changes",    savechanges,        1 },
  301. X    { "shell-escape",    shellescape,        0 },
  302. X#ifdef SENDMAIL
  303. X    { "unbind-group",    ubindgroup,        1 },
  304. X    { "unbind-class",    ubindclass,        1 },
  305. X    { "unbind-sig",        ubindsig,        1 },
  306. X    { "update-alias",    updalias,        1 },
  307. X#endif
  308. X    { "update-class",    updclass,        1 },
  309. X    { "update-group",    updgroup,        1 },
  310. X    { "update-range",    updrange,        1 },
  311. X    { "update-sig",        updsig,            1 },
  312. X    { "update-user",    upduser,        1 },
  313. X#ifdef HELPDIR
  314. X    { "what-is",        whatis,            0 },
  315. X#endif
  316. X    { (char *) 0,        (int (*)())0,        0 }
  317. X};
  318. X
  319. X#ifdef HELPDIR
  320. Xstatic    char *TermTable[] = {
  321. X# ifdef SENDMAIL
  322. X    "alias",
  323. X# endif
  324. X    "class",
  325. X    "cryo",
  326. X    "deadbeat",
  327. X    "gid",
  328. X    "inactive",
  329. X    "range",
  330. X    "sig",
  331. X    "uid",
  332. X    "vig",
  333. X    (char *)0
  334. X};
  335. X#endif
  336. X
  337. Xstruct    list TempLists;            /* list of lists to freed */
  338. X#ifdef SENDMAIL
  339. Xstruct    list Aliases;            /* alias name completion list */
  340. Xstruct    list AliasList;            /* list of alias structures */
  341. X#endif
  342. Xstruct    list AllCommands;        /* complete list of mcp commands */
  343. Xstruct    list Commands;            /* commands this user is allowed */
  344. Xstruct    list Users;            /* user name completion list */
  345. Xstruct    list AccountList;        /* list of account structures */
  346. Xstruct    list Classes;            /* class name completion list */
  347. Xstruct    list ClassList;            /* list of class structures */
  348. Xstruct    list Groups;            /* group name completion list */
  349. Xstruct    list GroupMapList;        /* list of groupmap structures */
  350. Xstruct    list Ranges;            /* range name completion list */
  351. Xstruct    list RangeList;            /* list of range structures */
  352. Xstruct    list Sigs;            /* sig name completion list */
  353. Xstruct    list SigList;            /* list of sig structures */
  354. Xstruct    list Jobs;            /* list of job structures */
  355. X#ifdef HELPDIR
  356. Xstruct    list Terms;            /* list of terms mcp can define */
  357. X#endif
  358. Xstruct    list Shells;            /* list of shells (from SHELLFILE) */
  359. Xstruct    list Vigs;            /* vig completion list */
  360. Xstruct    list Null_List;            /* empty list */
  361. X
  362. Xint    ModBits;            /* flags denoting modified files */
  363. Xint    DevTty;                /* descriptor for diagnostic output
  364. X                       and prompts. DevTty = 2 for non-
  365. X                       interactive runs. */
  366. Xtime_t    PWLockTime;            /* last modify time for /etc/passwd */
  367. Xint    root;                /* is this the super-user? */
  368. Xint    kids;                /* current # of child processes */
  369. Xint    NCommands;            /* # of commands user can execute */
  370. X
  371. Xaddr    DEF_SHELL;            /* default shell */
  372. Xchar    Working_Directory[LONG_BUF];    /* current working driectory */
  373. X#ifdef sun
  374. Xint    IsRemote;            /* must we use remote commands */
  375. Xchar    HostName[MEDIUM_BUF];        /* current hostname */
  376. X# ifdef DOFILES
  377. Xchar    FileServer[MEDIUM_BUF];        /* hostname of file server */
  378. Xchar    MountDirectory[MEDIUM_BUF];    /* remote mount point */
  379. Xchar    RemotePassword[SHORT_BUF];    /* root password of fileserver */
  380. Xu_short    ExecTcpPort;            /* port for exec/tcp service */
  381. X# endif
  382. X#endif
  383. X
  384. X
  385. Xinit_lists(interactive)
  386. Xint interactive;
  387. X
  388. X{
  389. X    FILE *fp;
  390. X    flexaddr p;
  391. X#ifdef SENDMAIL
  392. X    struct alias al, *al2;
  393. X    struct groupmap *gm2;
  394. X#endif
  395. X    struct account ac, *ac2;
  396. X    struct passwd *pw;
  397. X    struct group *gr;
  398. X    struct groupmap gm;
  399. X    struct sig sg, *sg2;
  400. X    struct class cs, *cs2;
  401. X    struct range rg, *rg2;
  402. X    struct lastlog *ll;
  403. X    char buf[LONG_BUF], errmsg[LONG_BUF], sh[MEDIUM_BUF], *cp;
  404. X    int indx, lineno = 0;
  405. X
  406. X    if (interactive) msg("Loading password and accounts...");
  407. X    (void) setpwent();
  408. X    (void) setacent();
  409. X    (void) setllent();
  410. X    while ((pw = getpwent()) != (struct passwd *)0) {
  411. X        ac2 = getacent();
  412. X        if (!ac2)
  413. X            fatal(e1);
  414. X        lineno++;
  415. X        if (!eq((char *)ac2->ac_name, pw->pw_name)) {
  416. X            (void) sprintf(errmsg, e3, lineno);
  417. X            fatal(errmsg);
  418. X        }
  419. X        ac.ac_uid = pw->pw_uid;
  420. X        ac.ac_gid = pw->pw_gid;
  421. X        savestr((char **)&ac.ac_name, pw->pw_name);
  422. X        savestr((char **)&ac.ac_gecos, pw->pw_gecos);
  423. X        savestr((char **)&ac.ac_passwd, pw->pw_passwd);
  424. X        savestr((char **)&ac.ac_dir, pw->pw_dir);
  425. X        savestr((char **)&ac.ac_shell, pw->pw_shell);
  426. X        savestr((char **)&ac.ac_realname, (char *)ac2->ac_realname);
  427. X        savestr((char **)&ac.ac_id, (char *)ac2->ac_id);
  428. X        duplist(&ac.ac_groups, &ac2->ac_groups);
  429. X        duplist(&ac.ac_classes, &ac2->ac_classes);
  430. X        duplist(&ac.ac_sigs, &ac2->ac_sigs);
  431. X#ifdef SENDMAIL
  432. X        duplist(&ac.ac_aliases, &ac2->ac_aliases);
  433. X#endif
  434. X        ll = getlluid(ac.ac_uid);
  435. X        bcopy(&ac.ac_ll, ll, sizeof (struct lastlog));
  436. X        genlistadd(&AccountList, (addr)&ac, sizeof (struct account));
  437. X        strlistadd(&Users, pw->pw_name);
  438. X    }
  439. X    (void) endpwent();
  440. X    endllent();
  441. X    if (getacent()) fatal(e2);
  442. X    (void) endacent();
  443. X
  444. X    if (interactive) msg("Loading groups...");
  445. X    zerolist(&gm.gm_aliases);
  446. X    (void) setgrent();
  447. X    while ((gr = getgrent()) != (struct group *)0) {
  448. X        zerolist(&gm.gm_mem);
  449. X#ifdef SENDMAIL
  450. X         zerolist(&gm.gm_aliases);
  451. X#endif
  452. X        gm.gm_gid = gr->gr_gid;
  453. X        savestr(&gm.gm_name, gr->gr_name);
  454. X        savestr(&gm.gm_passwd, gr->gr_passwd);
  455. X        for (indx=0; gr->gr_mem[indx]; indx++)
  456. X            strlistadd(&gm.gm_mem, gr->gr_mem[indx]);
  457. X        sort_list(&gm.gm_mem, pstrcmp);
  458. X        genlistadd(&GroupMapList, (addr)&gm, sizeof(struct groupmap));
  459. X        strlistadd(&Groups, gr->gr_name);
  460. X    }
  461. X    (void) endgrent();
  462. X    if (interactive) msg("Loading classes...");
  463. X#ifdef SENDMAIL
  464. X    zerolist(&cs.cs_aliases);
  465. X#endif
  466. X    setcsent();
  467. X    while (cs2 = getcsent()) {
  468. X        savestr(&cs.cs_name, cs2->cs_name);
  469. X        savestr(&cs.cs_desc, cs2->cs_desc);
  470. X        cs.cs_dsize = cs2->cs_dsize;
  471. X        cs.cs_exptime = cs2->cs_exptime;
  472. X        genlistadd(&ClassList, (addr)&cs, sizeof (struct class));
  473. X        strlistadd(&Classes, cs.cs_name);
  474. X    }
  475. X    endcsent();
  476. X    if (interactive) msg("Loading sigs...");
  477. X#ifdef SENDMAIL
  478. X    zerolist(&sg.sg_aliases);
  479. X#endif
  480. X    setsgent();
  481. X    while (sg2 = getsgent()) {
  482. X        savestr(&sg.sg_name, sg2->sg_name);
  483. X        savestr(&sg.sg_desc, sg2->sg_desc);
  484. X        sg.sg_dsize = sg2->sg_dsize;
  485. X        sg.sg_exptime = sg2->sg_exptime;
  486. X        genlistadd(&SigList, (addr)&sg, sizeof (struct sig));
  487. X        strlistadd(&Sigs, sg.sg_name);
  488. X    }
  489. X    endsgent();
  490. X    if (interactive) msg("Loading range table...");
  491. X    setrgent();
  492. X    while (rg2 = getrgent()) {
  493. X        savestr(&rg.rg_name, rg2->rg_name);
  494. X        rg.rg_mode = rg2->rg_mode;
  495. X        rg.rg_from = rg2->rg_from;
  496. X        rg.rg_to = rg2->rg_to;
  497. X        genlistadd(&RangeList, (addr)&rg, sizeof (struct range));
  498. X        strlistadd(&Ranges, rg.rg_name);
  499. X    }
  500. X    endrgent();
  501. X
  502. X    if (interactive) msg("Loading vigs...");
  503. X    fp = fopen(VIGFILE, "r");
  504. X    if (fp != NULL) {
  505. X        while (fscanf(fp, "%s", buf) != EOF)
  506. X            strlistadd(&Vigs, buf);
  507. X        (void) fclose(fp);
  508. X    }
  509. X
  510. X#ifdef SENDMAIL
  511. X    /*
  512. X     * Must sort here so that get{cs,gm,sg}nam() calls will work.
  513. X     */
  514. X    if (interactive) msg("Loading and binding sendmail aliases...");
  515. X    sort_list(&Groups, pstrcmp);
  516. X    sort_list(&ClassList, classcmp);
  517. X    sort_list(&SigList, sigcmp);
  518. X    setalent();
  519. X    while (al2 = getalent()) {
  520. X        savestr(&al.al_name, al2->al_name);
  521. X        duplist(&al.al_addresses, &al2->al_addresses);
  522. X        duplist(&al.al_groups, &al2->al_groups);
  523. X        duplist(&al.al_classes, &al2->al_classes);
  524. X        duplist(&al.al_sigs, &al2->al_sigs);
  525. X        genlistadd(&AliasList, (addr)&al, sizeof (struct alias));
  526. X        strlistadd(&Aliases, al.al_name);
  527. X        for (indx=0; indx < al.al_groups.l_count; indx++) {
  528. X            cp = (char *)al.al_groups.l_list[indx];
  529. X            gm2 = getgmnam(cp);
  530. X            if (!gm2)
  531. X                continue;
  532. X            strlistadd(&gm2->gm_aliases, al.al_name);
  533. X            sort_list(&gm2->gm_aliases, pstrcmp);
  534. X        }
  535. X        for (indx=0; indx < al.al_classes.l_count; indx++) {
  536. X            cp = (char *)al.al_classes.l_list[indx];
  537. X            cs2 = getcsnam(cp);
  538. X            if (!cs2)
  539. X                continue;
  540. X            strlistadd(&cs2->cs_aliases, al.al_name);
  541. X            sort_list(&cs2->cs_aliases, pstrcmp);
  542. X        }
  543. X        for (indx=0; indx < al.al_sigs.l_count; indx++) {
  544. X            cp = (char *)al.al_sigs.l_list[indx];
  545. X            sg2 = getsgnam(cp);
  546. X            if (!sg2)
  547. X                continue;
  548. X            strlistadd(&sg2->sg_aliases, al.al_name);
  549. X            sort_list(&sg2->sg_aliases, pstrcmp);
  550. X        }
  551. X    }
  552. X    endalent();
  553. X#endif
  554. X    /*
  555. X     * If this is not an interactive session there is no need
  556. X     * to initialize the lists that are only used when mcp
  557. X     * is running interactively.
  558. X     */
  559. X    if (!interactive) goto sort_em;
  560. X
  561. X    msg("Commands...");
  562. X    for (indx=0; Ctable[indx].c_name; indx++) {
  563. X        if (root || !Ctable[indx].c_su)
  564. X            strlistadd(&Commands, Ctable[indx].c_name);
  565. X        strlistadd(&AllCommands, Ctable[indx].c_name);
  566. X    }
  567. X    NCommands = indx;
  568. X    qsort((char *)Ctable, NCommands, sizeof (struct command), commcmp);
  569. X
  570. X#ifdef HELPDIR
  571. X    msg("Building term table...");
  572. X    for (indx=0; TermTable[indx]; indx++)
  573. X        strlistadd(&Terms, TermTable[indx]);
  574. X#endif
  575. X    msg("Loading shell table...");
  576. X    fp = fopen(SHELLFILE, "r");
  577. X    if (fp != NULL) {
  578. X        while (fgets(buf, LONG_BUF, fp) != NULL) {
  579. X            cp = index(buf, '#');
  580. X            if (cp) *cp = '\0';
  581. X            if (sscanf(buf, "%s", sh) != 1)
  582. X                continue;
  583. X            strlistadd(&Shells, sh);
  584. X        }
  585. X        (void) fclose(fp);
  586. X    }
  587. X    p.p_cp = (Shells.l_count ? (char *) Shells.l_list[0] : "/bin/sh");
  588. X    DEF_SHELL = p.p_ap;
  589. X
  590. Xsort_em:
  591. X    if (interactive) msg("Sorting lists...");
  592. X    sort_list(&AccountList, acctcmp);
  593. X    sort_list(&GroupMapList, gmapcmp);
  594. X    sort_list(&Users, pstrcmp);
  595. X    sort_list(&Classes, pstrcmp);
  596. X    sort_list(&Sigs, pstrcmp);
  597. X    sort_list(&Ranges, pstrcmp);
  598. X    sort_list(&RangeList, rangecmp);
  599. X    sort_list(&Vigs, pstrcmp);
  600. X#ifdef SENDMAIL
  601. X    sort_list(&AliasList, aliascmp);
  602. X    sort_list(&Aliases, pstrcmp);
  603. X#else
  604. X    sort_list(&Groups, pstrcmp);
  605. X    sort_list(&ClassList, classcmp);
  606. X    sort_list(&SigList, sigcmp);
  607. X#endif
  608. X    if (interactive) {
  609. X        sort_list(&Titles, pstrcmp);
  610. X        sort_list(&Suffixes, pstrcmp);
  611. X        sort_list(&YesNo, pstrcmp);
  612. X        sort_list(&Shells, pstrcmp);
  613. X        sort_list(&Commands, pstrcmp);
  614. X        sort_list(&AllCommands, pstrcmp);
  615. X#ifdef HELPDIR
  616. X        sort_list(&Terms, pstrcmp);
  617. X#endif
  618. X        msg("and...");
  619. X        zerolist(&History);
  620. X        zerolist(&TempLists);
  621. X        msg("");
  622. X    }
  623. X    return;
  624. X}
  625. X
  626. Xinit_tty(interactive)
  627. Xint interactive;
  628. X
  629. X{
  630. X    extern int errno;
  631. X    long lseek();
  632. X
  633. X    if (!interactive) {
  634. X        DevTty = 2;
  635. X        return;
  636. X    }
  637. X    if ((DevTty = open("/dev/tty", O_RDWR)) < 0) {
  638. X        perror("/dev/tty");
  639. X        goodbye(1);
  640. X    }
  641. X    if (lseek(0, 0L, L_INCR) == -1) {
  642. X        if (errno == ESPIPE)
  643. X        err("mcp reading from a pipe...");
  644. X    }
  645. X    else if (!isatty(0))
  646. X        err("mcp reading from a file...");
  647. X    return;
  648. X}
  649. X
  650. Xinit_identities()
  651. X
  652. X{
  653. X#ifdef sun
  654. X# ifdef DOFILES
  655. X    FILE *mnf;
  656. X    struct mntent *mn;
  657. X    struct servent *sv;
  658. X    char *cp, prompt[MEDIUM_BUF];
  659. X# endif
  660. X#endif
  661. X    root = !(getuid() && geteuid());
  662. X    if (!getwd(Working_Directory))
  663. X        fatal1("getwd() failed!?: %s", Working_Directory);
  664. X    srandom(getpid() + getppid() + time((time_t *)0));
  665. X#ifdef sun
  666. X    if (gethostname(HostName, MEDIUM_BUF) == -1) {
  667. X        perr("gethostname");
  668. X        fatal("mcp: Sorry, but I must have a hostname.");
  669. X    }
  670. X# ifdef DOFILES
  671. X    if (!root) return;
  672. X    mnf = setmntent(MNTTAB, "r");
  673. X    if (mnf == NULL) {
  674. X        fatal1("can't open %s", MNTTAB);
  675. X        goodbye(1);
  676. X    }
  677. X    while (mn = getmntent(mnf))
  678. X        if (eq(mn->mnt_dir, USERDIR))
  679. X            break;
  680. X    if (mn && eq(mn->mnt_type, "nfs")) {
  681. X        cp = index(mn->mnt_fsname, ':');
  682. X        *cp++ = '\0';
  683. X        (void) strcpy(FileServer, mn->mnt_fsname);
  684. X        (void) strcpy(MountDirectory, cp);
  685. X        sv = getservbyname("exec", "tcp");
  686. X        if (!sv)
  687. X            fatal("mcp: can't find service exec/tcp");
  688. X        ExecTcpPort = sv->s_port;
  689. X    /* root is not trusted over the network */
  690. X        (void) sprintf(prompt, "Root password on %s:", FileServer);
  691. X        cp = getpass(prompt);
  692. X        (void) strcpy(RemotePassword, cp);
  693. X        if (DoRemote("/bin/true") == 0)
  694. X            fatal("Sorry");
  695. X        IsRemote = 1;
  696. X    }
  697. X    (void) endmntent(mnf);
  698. X# endif
  699. X#endif
  700. X    return;
  701. X}
  702. @//E*O*F src/init.c//
  703. if test 16005 -ne "`wc -c <'src/init.c'`"; then
  704.     echo shar: error transmitting "'src/init.c'" '(should have been 16005 characters)'
  705. fi
  706. fi # end of overwriting check
  707. echo shar: extracting "'src/job.c'" '(8459 characters)'
  708. if test -f 'src/job.c' ; then 
  709.   echo shar: will not over-write existing file "'src/job.c'"
  710. else
  711. sed 's/^X//' >src/job.c <<'@//E*O*F src/job.c//'
  712. X/****************************************************************************\
  713. X*                                          *
  714. X*     job.c                                     *
  715. X*                                          *
  716. X* add_job()    add a job to the job list for later execution.             *
  717. X* do_jobs()    do the jobs in the job list.                     *
  718. X* rmmail()    remove a user's mail                         *
  719. X* rmsmail()    remove a user's secretmail                     *
  720. X* omni_chown()    change the ownership of all a user's files to another uid    *
  721. X*                                          *
  722. X* Also lastlog entries are updated here, although the actual routine that    *
  723. X* writes the file is in lastlog.c .  Directories are made and moved around   *
  724. X* here, but there are system calls that do these things.             *
  725. X*                                          *
  726. X\****************************************************************************/
  727. X
  728. X#include <stdio.h>
  729. X#include <strings.h>
  730. X#include <sys/wait.h>
  731. X#include <sys/types.h>
  732. X#include <sys/time.h>
  733. X#include <sys/resource.h
  734. X#include <sys/dir.h>
  735. X#include <lastlog.h>
  736. X#include "sysdep.h"
  737. X#include "mem.h"
  738. X#include "lists.h"
  739. X#include "job.h"
  740. X
  741. X#ifdef sun
  742. X# ifdef DOFILES
  743. Xextern    u_short ExecTcpPort;
  744. Xextern    char FileServer[], MountDirectory[], RemotePassword[];
  745. Xextern    int IsRemote;
  746. Xextern    char HostName[];
  747. X# endif
  748. X#endif
  749. Xextern    struct list Jobs;
  750. Xchar    *re_comp(), *sprintf();
  751. Xextern    int kids;
  752. X
  753. X/* ARGSUSED */
  754. Xadd_job(todo, arg1, arg2, arg3)
  755. Xint todo;
  756. Xaddr arg1, arg2, arg3;
  757. X
  758. X{
  759. X    struct job jb;
  760. X
  761. X    jb.jb_todo = todo;
  762. X    switch (jb.jb_todo) {
  763. X    case JB_LASTLOG:
  764. X        jb.jb_uid = (int) *arg1;
  765. X        jb.jb_addr = MEM(sizeof (struct lastlog));
  766. X        bcopy(jb.jb_addr, arg2, sizeof (struct lastlog));
  767. X        break;
  768. X
  769. X#ifdef DOFILES
  770. X    case JB_MKDIR:
  771. X        savestr(&jb.jb_name, (char *) arg1);
  772. X        jb.jb_uid = (int) *arg2;
  773. X        jb.jb_gid = (int) *arg3;
  774. X        break;
  775. X
  776. X    case JB_MV:
  777. X        savestr(&jb.jb_oldname, (char *) arg1);
  778. X        savestr(&jb.jb_name, (char *) arg2);
  779. X        break;
  780. X    case JB_RMDIR:
  781. X    case JB_RMMAIL:
  782. X        savestr(&jb.jb_name, (char *) arg1);
  783. X        break;
  784. X
  785. X    case JB_OMNICHOWN:
  786. X        jb.jb_olduid = (int) *arg1; 
  787. X        jb.jb_uid = (int) *arg2;
  788. X        break;
  789. X#endif
  790. X
  791. X    default:
  792. X        return;
  793. X    }
  794. X    genlistadd(&Jobs, (addr) &jb, sizeof (struct job));
  795. X    return;
  796. X}
  797. X
  798. Xdo_jobs()
  799. X
  800. X{
  801. X    struct job *jb;
  802. X    struct lastlog ll;
  803. X    int currjobs, success;
  804. X    char errmsg[LONG_BUF];
  805. X
  806. X    currjobs = Jobs.l_count;
  807. X    while (currjobs--) {
  808. X        jb = (struct job *) listpop(&Jobs);
  809. X        success = 0;
  810. X        switch (jb->jb_todo) {
  811. X        case JB_LASTLOG:
  812. X            bcopy(&ll, jb->jb_addr, sizeof (struct lastlog));
  813. X            addllent(&ll, jb->jb_uid);
  814. X            FREEMEM((char *)jb->jb_addr);
  815. X            success++;
  816. X            break;
  817. X
  818. X#ifdef DOFILES
  819. X        case JB_MKDIR:
  820. X# ifdef sun
  821. X            if (IsRemote) {
  822. X                success = makedir(jb->jb_name, 0755,
  823. X                        jb->jb_uid, jb->jb_gid);
  824. X                if (success) FREEMEM(jb->jb_name);
  825. X                break;
  826. X            }
  827. X            else
  828. X# endif
  829. X            /*
  830. X             * Here we assume if the mkdir() fails the  directory
  831. X             * must already be there.
  832. X             */
  833. X            if (mkdir(jb->jb_name, 0755) == 0) {
  834. X                (void) chown(jb->jb_name,
  835. X                        jb->jb_uid, jb->jb_gid);
  836. X            }
  837. X            FREEMEM(jb->jb_name);
  838. X            success++;
  839. X            break;
  840. X
  841. X        case JB_MV:
  842. X# ifdef sun
  843. X            if (IsRemote) {
  844. X                success=rrename(jb->jb_oldname, jb->jb_name);
  845. X                if (success) {
  846. X                    FREEMEM(jb->jb_name);
  847. X                    FREEMEM(jb->jb_oldname);
  848. X                }
  849. X            }
  850. X            else
  851. X# endif
  852. X            if (rename(jb->jb_oldname, jb->jb_name) == -1) {
  853. X                perr("rename");
  854. X                err2("rename %s -> %s failed.",
  855. X                    jb->jb_oldname,
  856. X                    jb->jb_name);
  857. X                break;
  858. X            }
  859. X            success++;
  860. X            FREEMEM(jb->jb_name);
  861. X            FREEMEM(jb->jb_oldname);
  862. X            break;
  863. X
  864. X        case JB_RMDIR:
  865. X            success = purge(jb->jb_name);
  866. X            if (!success) break;
  867. X            FREEMEM(jb->jb_name);
  868. X            break;
  869. X
  870. X        case JB_RMMAIL:
  871. X            success = rmmail(jb->jb_name) && rmsmail(jb->jb_name);
  872. X            if (!success) break;
  873. X            FREEMEM(jb->jb_name);
  874. X            break;
  875. X
  876. X        case JB_OMNICHOWN:
  877. X            success = omni_chown(jb->jb_olduid, jb->jb_uid);
  878. X            break;
  879. X#endif
  880. X        default:
  881. X            (void) sprintf(errmsg,
  882. X                "internal error: bad todo in job list (%d)",
  883. X                jb->jb_todo);
  884. X            err(errmsg);
  885. X            success++;    /* to get it out of the list */
  886. X            break;
  887. X        }
  888. X        if (success)
  889. X            FREEMEM((char *)jb);
  890. X        else
  891. X            genlistadd(&Jobs, (addr)jb, sizeof (struct job));
  892. X    }
  893. X    return;
  894. X}
  895. X
  896. X#ifdef DOFILES
  897. Xchar    **environ;
  898. X
  899. Xint
  900. Xpurge(path)
  901. Xchar *path;
  902. X
  903. X{
  904. X    char command[LONG_BUF];
  905. X    addr *v;
  906. X    int c, pid;
  907. X#ifdef sun
  908. X    int n;
  909. X
  910. X    n = strlen(USERDIR)-1;
  911. X    if (IsRemote && strncmp(path, USERDIR, n) == 0 && path[n] == '/') {
  912. X        (void) strcpy(command, RM);
  913. X        (void) strcat(command, " -rf ");
  914. X        (void) strcat(command, MountDirectory);
  915. X        (void) strcat(command, &path[n]);
  916. X        return (DoRemote(command) && !fileexists(path));
  917. X    }
  918. X#endif
  919. X    (void) strcpy(command, RM);
  920. X    (void) strcat(command, " -rf ");
  921. X    (void) strcat(command, path);
  922. X    c = cut(command);
  923. X    v = mkargv(command, c);
  924. X    pid = vfork();
  925. X    if (pid == -1) {
  926. X        err1("can't vfork to remove %s", path);
  927. X        return 0;
  928. X    }
  929. X    if (pid == 0) {
  930. X        execve((char *)v[0], (char **)v, environ);
  931. X        perr((char *)v[0]);
  932. X        _exit(1);
  933. X    }
  934. X    while (wait((union wait *)0) != pid)
  935. X        kids--;
  936. X    return !fileexists(path);
  937. X}
  938. X
  939. Xint
  940. Xrmmail(user)
  941. Xchar *user;
  942. X
  943. X{
  944. X    if (chdir(MAILSPOOL) == -1) {
  945. X        perr(SMAILSPOOL);
  946. X        return 0;
  947. X    }
  948. X    (void) unlink(user);
  949. X    return 1;
  950. X}
  951. X
  952. Xint
  953. Xrmsmail(user)
  954. Xchar *user;
  955. X
  956. X{
  957. X    DIR *dirp;
  958. X    char buf[MEDIUM_BUF];
  959. X    struct direct *dp;
  960. X
  961. X    if (chdir(SMAILSPOOL) == -1) {
  962. X        perr(SMAILSPOOL);
  963. X        return 0;
  964. X    }
  965. X    dirp = opendir(".");
  966. X    if (dirp == NULL) {
  967. X        err1("can't open %s (read)", SMAILSPOOL);
  968. X        return 0;
  969. X    }
  970. X    (void) sprintf(buf, "%s\\..*", user);
  971. X    (void) re_comp(buf);
  972. X    for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
  973. X        if (re_exec(dp->d_name) == 1)
  974. X            (void) unlink(dp->d_name);
  975. X    closedir(dirp);
  976. X    return 1;
  977. X}
  978. X
  979. X#define OMNIFMT "%s -15 %s %s -user %d -exec %s %d {} ;"
  980. X
  981. X/*
  982. X * When changing file ownerships on Sun's distributed filesystem, we
  983. X * must be careful not to disturb files belonging to a user with the same
  984. X * uid but on another machine!
  985. X */
  986. Xint
  987. Xomni_chown(ouid, nuid)
  988. Xint ouid, nuid;
  989. X
  990. X{
  991. X    char command[LONG_BUF];
  992. X# ifdef sun
  993. X    char dirbuf[MEDIUM_BUF];
  994. X
  995. X    if (IsRemote) {
  996. X(void)sprintf(command, OMNIFMT, NICE, FIND, MountDirectory, ouid, CHOWN,nuid);
  997. X        (void) strcat(command, " &");
  998. X        if (DoRemote(command) == 0) return 0;
  999. X    }
  1000. X    else {
  1001. X        (void) sprintf(dirbuf, "%s/%s", USERDIR, HostName);
  1002. X(void) sprintf(command, OMNIFMT, NICE, FIND, dirbuf, ouid, CHOWN, nuid);
  1003. X        if (BackGround(command) == 0) return 0;
  1004. X    }
  1005. X(void) sprintf(command, OMNIFMT, NICE, FIND, SMAILSPOOL, ouid, CHOWN, nuid);
  1006. X    if (BackGround(command) == 0) return 0;
  1007. X(void) sprintf(command, OMNIFMT, NICE, FIND, MAILSPOOL, ouid, CHOWN, nuid);
  1008. X    if (BackGround(command) == 0) return 0;
  1009. X# else
  1010. X    (void) sprintf(command, OMNIFMT, NICE, FIND, "/", ouid, CHOWN, nuid);
  1011. X    if (BackGround(command) == 0) return 0;
  1012. X# endif
  1013. X    return 1;
  1014. X}
  1015. X
  1016. XBackGround(command)
  1017. Xchar *command;
  1018. X
  1019. X{
  1020. X    int c, pid;
  1021. X    addr *v;
  1022. X
  1023. X    c = cut(command);
  1024. X    v = mkargv(command, c);
  1025. X
  1026. X    pid = vfork();
  1027. X    if (pid == -1) {
  1028. X        perr("can't vfork");
  1029. X        return 0;
  1030. X    }
  1031. X    kids++;
  1032. X    if (pid == 0) {
  1033. X        (void) setpgrp(0, getpid());
  1034. X        execve((char *)*v, (char **)v, environ);
  1035. X        perr((char *)*v);
  1036. X        _exit(1);
  1037. X    }
  1038. X    (void) setpriority(PRIO_PROCESS, pid, 15);
  1039. X    return 1;
  1040. X}
  1041. X
  1042. X# ifdef sun
  1043. X
  1044. Xrrename(from, to)
  1045. Xchar *from, *to;
  1046. X
  1047. X{
  1048. X    int n;
  1049. X    char command[LONG_BUF];
  1050. X
  1051. X    n = strlen(USERDIR)-1;
  1052. X    if (strncmp(from, USERDIR, n) || from[n] != '/') {
  1053. X        err2("rrename: %s not in %s", from, USERDIR);
  1054. X        return 0;
  1055. X    }
  1056. X    if (strncmp(to, USERDIR, n) || from[n] != '/') {
  1057. X        err2("rrename: %s not in %s", from, USERDIR);
  1058. X        return 0;
  1059. X    }
  1060. X    (void) sprintf(command, "%s %s%s %s%s", MV, MountDirectory,
  1061. X            &from[n], MountDirectory, &to[n]);
  1062. X    return ((!DoRemote(command)) || fileexists(from) || !fileexists(to))
  1063. X        ? 0 : 1;
  1064. X}
  1065. X
  1066. Xmakedir(path, mode, uid, gid)
  1067. Xchar *path;
  1068. Xint mode, uid, gid;
  1069. X
  1070. X{
  1071. X    int n;
  1072. X    char command[LONG_BUF];
  1073. X
  1074. X    n = strlen(USERDIR);
  1075. X    if (strncmp(path, USERDIR, n) || path[n] != '/') {
  1076. X        err2("makedir: %s not in %s", path, USERDIR);
  1077. X        return 0;
  1078. X    }
  1079. X(void)    sprintf(command, "%s %s%s", MKDIR, MountDirectory, &path[n]);
  1080. X    (void) DoRemote(command);
  1081. X(void)    sprintf(command, "%s %d %s%s", CHOWN, uid, MountDirectory, &path[n]);
  1082. X    (void) DoRemote(command);
  1083. X(void)    sprintf(command, "%s %d %s%s", CHGRP, gid, MountDirectory, &path[n]);
  1084. X    (void) DoRemote(command);
  1085. X(void)    sprintf(command, "%s %o %s%s", CHMOD, mode, MountDirectory, &path[n]);
  1086. X    (void) DoRemote(command);
  1087. X    return 1;
  1088. X}
  1089. X
  1090. Xstatic
  1091. XTweedle(d)
  1092. Xint d;
  1093. X
  1094. X{
  1095. X    char c;
  1096. X
  1097. X    (void) shutdown(d, 1);
  1098. X    while (read(d, &c, 1) == 1)
  1099. X        (void) write(1, &c, 1);
  1100. X    (void) fsync(1);
  1101. X    return;
  1102. X}
  1103. X
  1104. Xint
  1105. XDoRemote(command)
  1106. Xchar *command;
  1107. X
  1108. X{
  1109. X    char f[MEDIUM_BUF], *h[1];
  1110. X    int d;
  1111. X
  1112. X    (void) strcpy(f, FileServer);
  1113. X    *h = f;
  1114. X    d = rexec(h, ExecTcpPort, "root", RemotePassword, command, (int *)0);
  1115. X    if (d == -1) return 0;
  1116. X    Tweedle(d);
  1117. X    (void) close(d);
  1118. X    return 1;
  1119. X}
  1120. X
  1121. X# endif
  1122. X#endif
  1123. @//E*O*F src/job.c//
  1124. if test 8459 -ne "`wc -c <'src/job.c'`"; then
  1125.     echo shar: error transmitting "'src/job.c'" '(should have been 8459 characters)'
  1126. fi
  1127. fi # end of overwriting check
  1128. echo shar: extracting "'src/lastlog.c'" '(1294 characters)'
  1129. if test -f 'src/lastlog.c' ; then 
  1130.   echo shar: will not over-write existing file "'src/lastlog.c'"
  1131. else
  1132. sed 's/^X//' >src/lastlog.c <<'@//E*O*F src/lastlog.c//'
  1133. X#include <sys/file.h>
  1134. X#include <stdio.h>
  1135. X#include <sys/types.h>
  1136. X#include <lastlog.h>
  1137. X#include "sysdep.h"
  1138. X#include "mem.h"
  1139. X#include "save.h"
  1140. X
  1141. Xstatic    struct lastlog zero;
  1142. Xstruct    lastlog ll;
  1143. Xlong    lseek();
  1144. X
  1145. Xint LL_FileDes = UNDEFINED;
  1146. X
  1147. Xsetllent()
  1148. X
  1149. X{
  1150. X    if (LL_FileDes == UNDEFINED) {
  1151. X        LL_FileDes = open(LASTLOG, O_RDONLY);
  1152. X        if (LL_FileDes < 0) {
  1153. X            perr(LASTLOG);
  1154. X            goodbye(1);
  1155. X        }
  1156. X    }
  1157. X    lseek(LL_FileDes, (long)0, L_SET)<0&&perr("setllent: lseek failed?!");
  1158. X    return;
  1159. X}
  1160. X
  1161. Xendllent()
  1162. X
  1163. X{
  1164. X    if (LL_FileDes == UNDEFINED)
  1165. X        return;
  1166. X    (void) close(LL_FileDes);
  1167. X    LL_FileDes = UNDEFINED;
  1168. X    return;
  1169. X}
  1170. X
  1171. Xstruct lastlog *
  1172. Xgetllent()
  1173. X
  1174. X{
  1175. X    if (LL_FileDes == UNDEFINED)
  1176. X        setllent();
  1177. X    if (read(LL_FileDes, (char *)&ll, sizeof ll) != sizeof ll)
  1178. X        return(&zero);
  1179. X    else
  1180. X        return(&ll);
  1181. X}
  1182. X
  1183. Xstruct lastlog *
  1184. Xgetlluid(uid)
  1185. Xint uid;
  1186. X
  1187. X{
  1188. X    if (LL_FileDes == UNDEFINED)
  1189. X        setllent();
  1190. X    lseek(LL_FileDes, (long)(uid * sizeof(struct lastlog)), L_SET)<0
  1191. X        && perr("getlluid: lseek failed!?");
  1192. X    return(getllent());
  1193. X}
  1194. X
  1195. Xaddllent(lp, uid)
  1196. Xstruct lastlog *lp;
  1197. Xint uid;
  1198. X
  1199. X{
  1200. X    int fd;
  1201. X
  1202. X    fd = open(LASTLOG, O_WRONLY);
  1203. X    if (fd < 0) {
  1204. X        perr(LASTLOG);
  1205. X        return;
  1206. X    }
  1207. X    lseek(fd, (long)(uid * sizeof(struct lastlog)), L_SET)<0&&
  1208. X        panic("addllent: lseek failed!?");
  1209. X    (void) write(fd, (char *)lp, sizeof(struct lastlog));
  1210. X    (void) close(fd);
  1211. X    return;
  1212. X}
  1213. @//E*O*F src/lastlog.c//
  1214. if test 1294 -ne "`wc -c <'src/lastlog.c'`"; then
  1215.     echo shar: error transmitting "'src/lastlog.c'" '(should have been 1294 characters)'
  1216. fi
  1217. fi # end of overwriting check
  1218. echo shar: extracting "'src/list.c'" '(3995 characters)'
  1219. if test -f 'src/list.c' ; then 
  1220.   echo shar: will not over-write existing file "'src/list.c'"
  1221. else
  1222. sed 's/^X//' >src/list.c <<'@//E*O*F src/list.c//'
  1223. X/****************************************************************************\
  1224. X*                                          *
  1225. X*     list.c                                     *
  1226. X*                                          *
  1227. X* Code for the list- commands.  listgeneric() just chooses and prints the    *
  1228. X* appropriate completion list.  The other routines handle special cases for  *
  1229. X* which there are no completion lists kept.                     *
  1230. X*                                          *
  1231. X\****************************************************************************/
  1232. X
  1233. X#include <stdio.h>
  1234. X#include <sys/types.h>
  1235. X#include <lastlog.h>
  1236. X#include "sysdep.h"
  1237. X#include "macros.h"
  1238. X#include "mem.h"
  1239. X#include "lists.h"
  1240. X#include "account.h"
  1241. X#ifdef SENDMAIL
  1242. X#include "alias.h"
  1243. X#endif
  1244. X#include "groupmap.h"
  1245. X#include "job.h"
  1246. X
  1247. X#ifdef BSD4_3
  1248. Xtime_t    time();
  1249. X#endif
  1250. X
  1251. X#ifdef SENDMAIL
  1252. Xextern    struct list Aliases;
  1253. X#endif
  1254. Xextern    struct list Users, Groups, Vigs, Ranges, Classes, Sigs;
  1255. Xextern    struct list AccountList, AllCommands;
  1256. Xchar    *sprintf();
  1257. Xstruct     list *picklist();
  1258. Xstatic    char *allv[2] = { ".*", 0 };
  1259. X
  1260. Xlistgeneric(c, v)
  1261. Xint c;
  1262. Xaddr *v;
  1263. X
  1264. X{
  1265. X    int count;
  1266. X    struct list *List;
  1267. X
  1268. X    List = picklist((char *)v[0]);
  1269. X    c--; v++;
  1270. X    if (c == 0) {
  1271. X        (void) showlist(List, (addr *)allv);
  1272. X        count = List->l_count;
  1273. X    }
  1274. X    else
  1275. X        count = showlist(List, v);
  1276. X    if (count)
  1277. X        (void) printf("%d listed\n", count);
  1278. X    return;
  1279. X}
  1280. X
  1281. Xlistcryos(c, v)
  1282. Xint c;
  1283. Xaddr *v;
  1284. X
  1285. X{
  1286. X    static struct list cryos;
  1287. X    struct account *ac;
  1288. X    int indx, count;
  1289. X
  1290. X    zerolist(&cryos);
  1291. X    tmplistadd(&cryos);
  1292. X    for (indx=0; indx < AccountList.l_count; indx++) {
  1293. X        ac = (struct account *) AccountList.l_list[indx];
  1294. X        if (eq((char *)ac->ac_shell, FREEZE_SH))
  1295. X            strlistadd(&cryos, (char *)ac->ac_name);
  1296. X    }
  1297. X    c--; v++;
  1298. X    if (c == 0) {
  1299. X        (void) showlist(&cryos, (addr *)allv);
  1300. X        count = cryos.l_count;
  1301. X    }
  1302. X    else
  1303. X        count = showlist(&cryos, v);
  1304. X    if (count)
  1305. X        (void) printf("%d listed\n", count);
  1306. X    return;
  1307. X}
  1308. X
  1309. Xlistdeadbeats(c, v)
  1310. Xint c;
  1311. Xaddr *v;
  1312. X
  1313. X{
  1314. X    static struct list deadbeats;
  1315. X    struct account *ac;
  1316. X    struct groupmap *gm;
  1317. X    int indx, count;
  1318. X    char errmsg[LONG_BUF];
  1319. X
  1320. X    zerolist(&deadbeats);
  1321. X    tmplistadd(&deadbeats);
  1322. X    for (indx=0; indx < AccountList.l_count; indx++) {
  1323. X        ac = (struct account *) AccountList.l_list[indx];
  1324. X        if (ac->ac_classes.l_count)
  1325. X            continue;
  1326. X        if (ac->ac_sigs.l_count)
  1327. X            continue;
  1328. X        /*
  1329. X         * Cryos are not deadbeats.
  1330. X         */
  1331. X        if (eq(ac->ac_shell, FREEZE_SH))
  1332. X            continue;
  1333. X        gm = getgmgid(ac->ac_gid);
  1334. X        if (!gm) {
  1335. X            (void) sprintf(errmsg,
  1336. X                    "no group for gid %d!",
  1337. X                    ac->ac_gid);
  1338. X            err(errmsg);
  1339. X            return;
  1340. X        }
  1341. X        if (vigexists(gm->gm_name))
  1342. X            continue;
  1343. X        strlistadd(&deadbeats, (char *)ac->ac_name);
  1344. X    }
  1345. X    c--; v++;
  1346. X    if (c == 0) {
  1347. X        (void) showlist(&deadbeats, (addr *)allv);
  1348. X        count = deadbeats.l_count;
  1349. X    }
  1350. X    else
  1351. X        count = showlist(&deadbeats, v);
  1352. X    if (count)
  1353. X        (void) printf("%d listed\n", count);
  1354. X    return;
  1355. X}
  1356. X
  1357. Xlistinactives(c, v)
  1358. Xint c;
  1359. Xaddr *v;
  1360. X
  1361. X{
  1362. X    static struct list inactives;
  1363. X    struct account *ac;
  1364. X    struct groupmap *gm;
  1365. X    int indx, count;
  1366. X    time_t now;
  1367. X    long toolong;
  1368. X    char errmsg[LONG_BUF];
  1369. X
  1370. X    if ( c < 2 ) {
  1371. X        err1("usage: %s <days> [expr ...]", (char *)v[0]);
  1372. X        return;
  1373. X    }
  1374. X    if (!validint((char *)v[1])) {
  1375. X        err2("%s: %s doesn't make sense as a number", (char *)v[0],
  1376. X            (char *)v[1]);
  1377. X        return;
  1378. X    }
  1379. X    toolong = atoi((char *)v[1]) * 86400;
  1380. X
  1381. X    zerolist(&inactives);
  1382. X    tmplistadd(&inactives);
  1383. X    now = time((time_t *)0);
  1384. X    for (indx=0; indx < AccountList.l_count; indx++) {
  1385. X        ac = (struct account *) AccountList.l_list[indx];
  1386. X        if ((long)(now - ac->ac_ll.ll_time) < toolong)
  1387. X            continue;
  1388. X        /*
  1389. X         * Cryos are not inactive.
  1390. X         */
  1391. X        if (eq(ac->ac_shell, FREEZE_SH))
  1392. X            continue;
  1393. X        /*
  1394. X         * Vig members are not inactive.
  1395. X         */
  1396. X        gm = getgmgid(ac->ac_gid);
  1397. X        if (!gm) {
  1398. X            (void) sprintf(errmsg,
  1399. X                    "no group for gid %d!",
  1400. X                    ac->ac_gid);
  1401. X            err(errmsg);
  1402. X            return;
  1403. X        }
  1404. X        if (vigexists(gm->gm_name))
  1405. X            continue;
  1406. X        strlistadd(&inactives, (char *)ac->ac_name);
  1407. X    }
  1408. X    c -= 2;
  1409. X    v += 2;
  1410. X    if (c == 0) {
  1411. X        (void) showlist(&inactives, (addr *)allv);
  1412. X        count = inactives.l_count;
  1413. X    }
  1414. X    else
  1415. X        count = showlist(&inactives, v);
  1416. X    if (count)
  1417. X        (void) printf("%d listed\n", count);
  1418. X    return;
  1419. X}
  1420. @//E*O*F src/list.c//
  1421. if test 3995 -ne "`wc -c <'src/list.c'`"; then
  1422.     echo shar: error transmitting "'src/list.c'" '(should have been 3995 characters)'
  1423. fi
  1424. fi # end of overwriting check
  1425. echo shar: extracting "'src/lists.c'" '(9337 characters)'
  1426. if test -f 'src/lists.c' ; then 
  1427.   echo shar: will not over-write existing file "'src/lists.c'"
  1428. else
  1429. sed 's/^X//' >src/lists.c <<'@//E*O*F src/lists.c//'
  1430. X/************************************************************************\
  1431. X*                                      *
  1432. X*     lists.c                                 *
  1433. X*                                      *
  1434. X* Routines to maintain, scan and manipulate the generic list structures     *
  1435. X* that permeate the program.  Some of the most oft used routines:     *
  1436. X*                                      *
  1437. X* strlistadd()    add to a list of strings                 *
  1438. X* genlistadd()    add an abitrary object to a list             *
  1439. X* strlistdel()    delete a string from a list                 *
  1440. X* genlistdel()    delete an abitrary object from a list             *
  1441. X* search_list()    search a list for a particular item             *
  1442. X* tmplistadd()    add a list pointer to the queue of string lists         *
  1443. X*         that is freed just before mcp prompt for another     *
  1444. X*         command                             *
  1445. X* freelist()    free all memory associated with a list structure     *
  1446. X* listpop()    pop the first pointer from a list             *
  1447. X* orstrlist()    make the union of two string lists             *
  1448. X*                                      *
  1449. X\************************************************************************/
  1450. X
  1451. X#include <stdio.h>
  1452. X#include <strings.h>
  1453. X#include <ctype.h>
  1454. X#include "sysdep.h"
  1455. X#include "macros.h"
  1456. X#include "mem.h"
  1457. X#include "gpa.h"
  1458. X#include "lists.h"
  1459. X#include "sort.h"
  1460. X
  1461. Xextern    struct list TempLists;
  1462. X
  1463. Xchar *
  1464. Xskipspace(s)
  1465. Xchar *s;
  1466. X
  1467. X{
  1468. X    while (*s && isspace(*s))
  1469. X        s++;
  1470. X    return(s);
  1471. X}
  1472. X
  1473. X/*
  1474. X *    Cuts a string of space separated words into a series of null separated
  1475. X *    words.  Spaces may be imbedded in words only when the word is surround
  1476. X *    ed by double quotes [""]. Returns the number of words in the string.
  1477. X */
  1478. Xint cut(line)
  1479. Xchar *line;
  1480. X
  1481. X{
  1482. X    int wc = 0;
  1483. X    register char *cp;
  1484. X
  1485. X    cp = line;
  1486. X    if (*line == '\0')
  1487. X        return(0);
  1488. X    while ( *line != '\0' ) {
  1489. X        if ( isspace(*line) ) {
  1490. X            *cp++ = '\0';
  1491. X            line++;
  1492. X            line = skipspace(line);
  1493. X        }
  1494. X        else {
  1495. X            wc++;
  1496. X            while ( *line ) {
  1497. X                if (*line == '"') {
  1498. X                    *cp++ = *line++;
  1499. X                    while (*line && *line != '"')
  1500. X                        *cp++ = *line++;
  1501. X                    if (*line == '\0')
  1502. X                        break;
  1503. X                }
  1504. X                else if (isspace(*line))
  1505. X                    break;
  1506. X                *cp++ = *line++;
  1507. X            }
  1508. X        }
  1509. X    }
  1510. X    return(wc);
  1511. X}
  1512. X
  1513. X/*
  1514. X *    Makes a vector of pointers to the null separated strings pointed
  1515. X *    to by line.  The number count is needed to keep the thing from 
  1516. X *    going on forever.  Note the arg vector is in a static area, and
  1517. X *    is overwritten by subsequent calls.
  1518. X */
  1519. Xaddr *
  1520. Xmkargv(line, n)
  1521. Xchar *line;
  1522. Xint n;
  1523. X
  1524. X{
  1525. X    static addr argv[G_P_A__SIZE];
  1526. X    int i;
  1527. X    flexaddr p;
  1528. X
  1529. X    i = 0;
  1530. X    p.p_cp = line;
  1531. X    while ( i < n && i < 128) {
  1532. X        argv[i] = p.p_ap;
  1533. X        p.p_cp += strlen(p.p_cp) + 1;
  1534. X        i++;
  1535. X    }
  1536. X    argv[i] = NIL;
  1537. X    return(argv);
  1538. X}
  1539. X
  1540. X/*
  1541. X * Globs the arguments of an argv-like vector into a single string.
  1542. X */
  1543. Xaddr
  1544. Xglob(v)
  1545. Xaddr *v;
  1546. X
  1547. X{
  1548. X    static addr_t gob[LONG_BUF];
  1549. X    flexaddr p;
  1550. X
  1551. X    p.p_ap = gob;
  1552. X    p.p_cp[0] = '\0';
  1553. X    while ( *v ) {
  1554. X        (void) strcat(p.p_cp, (char *)*v++);
  1555. X        (void) strcat(p.p_cp, " ");
  1556. X    }
  1557. X    p.p_cp[strlen(p.p_cp)-1] = '\0';    /* remove trailing blank */
  1558. X    return(gob);
  1559. X}
  1560. X
  1561. Xparse_line(line, cc, vv)
  1562. Xchar *line;
  1563. Xint *cc;
  1564. Xaddr **vv;
  1565. X
  1566. X{
  1567. X    *cc = cut(line);
  1568. X    *vv = mkargv(line, *cc);
  1569. X    return;
  1570. X}
  1571. X
  1572. Xfreeargv(v)
  1573. Xaddr *v;
  1574. X
  1575. X{
  1576. X    critical();
  1577. X    while (*v) {
  1578. X        FREEMEM((char *)*v);
  1579. X        *v++ = NIL;
  1580. X    }
  1581. X    non_critical();
  1582. X}
  1583. X
  1584. Xint
  1585. Xsearch_list(l, s, compfunc, found)
  1586. Xstruct list *l;
  1587. Xchar *s;
  1588. Xint (*compfunc)(), *found;
  1589. X
  1590. X{
  1591. X    int lo = 0, hi = l->l_count - 1, middle, compval;
  1592. X
  1593. X    *found = 0;
  1594. X    while (lo < hi) {
  1595. X        middle = (lo + hi) / 2;
  1596. X        if ((compval = (*compfunc)(s, l->l_list[middle])) == 0) {
  1597. X            *found = 1;
  1598. X            return middle;
  1599. X        }
  1600. X        else if (compval < 0) {
  1601. X            decr(middle);
  1602. X            hi = middle;
  1603. X        }
  1604. X        else
  1605. X            lo = middle + 1;
  1606. X    }
  1607. X    if (l->l_count && ((*compfunc)(s, l->l_list[lo])) == 0)
  1608. X        *found = 1;
  1609. X    return lo;
  1610. X}
  1611. X
  1612. Xfreelist(l)
  1613. Xstruct list *l;
  1614. X
  1615. X{
  1616. X    register int i;
  1617. X
  1618. X    critical();
  1619. X    for (i=0; i<l->l_count; i++)
  1620. X        FREEMEM((char *)l->l_list[i]);
  1621. X    if (l->l_spacefor > 0)
  1622. X        FREEMEM((char *)l->l_list);
  1623. X    l->l_count = l->l_spacefor = 0;
  1624. X    non_critical();
  1625. X    return;
  1626. X}
  1627. X
  1628. Xstrlistadd(l, s)
  1629. Xstruct list *l;
  1630. Xchar *s;
  1631. X
  1632. X{
  1633. X    critical();
  1634. X    if (l->l_spacefor == 0) {
  1635. X        l->l_list = (addr *) MEM(STARTSIZE * sizeof (addr));
  1636. X        l->l_spacefor = STARTSIZE;
  1637. X    }
  1638. X    else if (l->l_count == l->l_spacefor) {
  1639. X        l->l_list = (addr *) DELTAMEM((addr)l->l_list,
  1640. X                    2 * l->l_spacefor * sizeof(addr));
  1641. X        l->l_spacefor *= 2;
  1642. X    }
  1643. X    savestr((char **)&l->l_list[l->l_count], s);
  1644. X    l->l_count++;
  1645. X    non_critical();
  1646. X    return;
  1647. X}
  1648. X
  1649. Xgenlistadd(l, p, n)
  1650. Xregister struct list *l;
  1651. Xregister addr p;
  1652. Xint n;
  1653. X
  1654. X{
  1655. X    critical();
  1656. X    if (l->l_spacefor == 0) {
  1657. X        l->l_list = (addr *) MEM(STARTSIZE * sizeof (addr));
  1658. X        l->l_spacefor = STARTSIZE;
  1659. X    }
  1660. X    else if (l->l_count == l->l_spacefor) {
  1661. X        l->l_list = (addr *) DELTAMEM((addr)l->l_list,
  1662. X                    2 * l->l_spacefor * sizeof (addr));
  1663. X        l->l_spacefor *= 2;
  1664. X    }
  1665. X    l->l_list[l->l_count] = MEM(n);
  1666. X    bcopy(l->l_list[l->l_count], p, n);
  1667. X    l->l_count++;
  1668. X    non_critical();
  1669. X    return;
  1670. X}
  1671. X
  1672. Xlistadd(l, p)
  1673. Xstruct list *l;
  1674. Xaddr p;
  1675. X
  1676. X{
  1677. X    critical();
  1678. X    if (l->l_spacefor == 0) {
  1679. X        l->l_list = (addr *) MEM(STARTSIZE * sizeof (addr));
  1680. X        l->l_spacefor = STARTSIZE;
  1681. X    }
  1682. X    else if (l->l_count == l->l_spacefor) {
  1683. X        l->l_list = (addr *) DELTAMEM((addr)l->l_list,
  1684. X                    2 * l->l_spacefor * sizeof (addr));
  1685. X        l->l_spacefor *= 2;
  1686. X    }
  1687. X    l->l_list[l->l_count] = p;
  1688. X    l->l_count++;
  1689. X    non_critical();
  1690. X    return;
  1691. X}
  1692. X
  1693. Xstrlistdel(l, s)
  1694. Xstruct list *l;
  1695. Xchar *s;
  1696. X
  1697. X{
  1698. X    register int i;
  1699. X    int found, indx, halfavail;
  1700. X
  1701. X    critical();
  1702. X    indx = search_list(l, s, strcmp, &found);
  1703. X    if (found) {
  1704. X        FREEMEM((char *)l->l_list[indx]);
  1705. X        for (i=indx; i<l->l_count-1; i++)
  1706. X            l->l_list[i] = l->l_list[i+1];
  1707. X        l->l_count--;
  1708. X        halfavail = l->l_spacefor / 2;
  1709. X        if (l->l_count < halfavail && l->l_spacefor > STARTSIZE) {
  1710. X            l->l_list = (addr *) DELTAMEM((addr)l->l_list,
  1711. X                        halfavail * sizeof (addr));
  1712. X            l->l_spacefor = halfavail;
  1713. X        }
  1714. X    }
  1715. X    non_critical();
  1716. X    return;
  1717. X}
  1718. X
  1719. Xgenlistdel(l, p, compfunc)
  1720. Xstruct list *l;
  1721. Xaddr p;
  1722. Xint (*compfunc)();
  1723. X
  1724. X{
  1725. X    register int i;
  1726. X    int found, indx, halfavail;
  1727. X
  1728. X    critical();
  1729. X    indx = search_list(l, (char *)p, compfunc, &found);
  1730. X    if (found) {
  1731. X        FREEMEM((char *)l->l_list[indx]);
  1732. X        for (i=indx; i<l->l_count-1; i++)
  1733. X            l->l_list[i] = l->l_list[i+1];
  1734. X        l->l_count--;
  1735. X        halfavail = l->l_spacefor / 2;
  1736. X        if (l->l_count < halfavail && l->l_spacefor > STARTSIZE) {
  1737. X            l->l_list = (addr *) DELTAMEM((addr)l->l_list,
  1738. X                        halfavail * sizeof (addr));
  1739. X            l->l_spacefor = halfavail;
  1740. X        }
  1741. X    }
  1742. X    non_critical();
  1743. X    return;
  1744. X}
  1745. X
  1746. Xint
  1747. Xstrlistchg(l, old, new)
  1748. Xstruct list *l;
  1749. Xchar *old, *new;
  1750. X
  1751. X{
  1752. X    int found, indx;
  1753. X
  1754. X    indx = search_list(l, old, strcmp, &found);
  1755. X    if (!found)
  1756. X        return 0;
  1757. X    FREEMEM((char *)l->l_list[indx]);
  1758. X    savestr((char **)&l->l_list[indx], new);
  1759. X    sort_list(l, pstrcmp);
  1760. X    return 1;
  1761. X}
  1762. X
  1763. Xaddr
  1764. Xlistpop(l)
  1765. Xstruct list *l;
  1766. X
  1767. X{
  1768. X    register int i;
  1769. X    addr first;
  1770. X    int halfavail;
  1771. X
  1772. X    critical();
  1773. X    first = l->l_list[0];
  1774. X    for (i=0; i<l->l_count-1; i++)
  1775. X        l->l_list[i] = l->l_list[i+1];
  1776. X    l->l_count--;
  1777. X    halfavail = l->l_spacefor / 2;
  1778. X    if (l->l_count < halfavail && l->l_spacefor > STARTSIZE) {
  1779. X        l->l_list = (addr *) DELTAMEM((addr)l->l_list,
  1780. X                        halfavail * sizeof (addr));
  1781. X        l->l_spacefor = halfavail;
  1782. X    }
  1783. X    non_critical();
  1784. X    return first;
  1785. X}
  1786. X
  1787. Xint
  1788. Xinstrlist(l, s)
  1789. Xstruct list *l;
  1790. Xchar *s;
  1791. X
  1792. X{
  1793. X    int found;
  1794. X
  1795. X    (void) search_list(l, s, strcmp, &found);
  1796. X    return found;
  1797. X}
  1798. X
  1799. Xzerolist(l)
  1800. Xstruct list *l;
  1801. X
  1802. X{
  1803. X    l->l_count = 0;
  1804. X    l->l_spacefor = 0;
  1805. X}
  1806. X
  1807. Xduplist(new, old)
  1808. Xstruct list *new, *old;
  1809. X
  1810. X{
  1811. X    critical();
  1812. X    new->l_count = old->l_count;
  1813. X    new->l_spacefor = old->l_spacefor;
  1814. X    new->l_list = old->l_list;
  1815. X    non_critical();
  1816. X    return;
  1817. X}
  1818. X
  1819. X/*
  1820. X**copylist(dest, src, objsize)
  1821. X**struct list *dest, *src;
  1822. X**int objsize;
  1823. X**
  1824. X**{
  1825. X**    register int i;
  1826. X**
  1827. X**    zerolist(dest);
  1828. X**    for (i=0; i<src->l_count; i++)
  1829. X**        genlistadd(dest, src->l_list[i], objsize);
  1830. X**    return;
  1831. X**}
  1832. X */
  1833. X
  1834. Xint
  1835. Xorstrlist(l, ll)
  1836. Xstruct list *l, *ll;
  1837. X
  1838. X{
  1839. X    register int indx;
  1840. X    int changed = 0;
  1841. X
  1842. X    for (indx=0; indx<ll->l_count; indx++) {
  1843. X        if (instrlist(l, (char *)ll->l_list[indx]))
  1844. X            continue;
  1845. X        changed++;
  1846. X        strlistadd(l, (char *)ll->l_list[indx]);
  1847. X        sort_list(l, pstrcmp);
  1848. X    }
  1849. X    return changed;
  1850. X}
  1851. X
  1852. Xtmplistadd(l)
  1853. Xstruct list *l;
  1854. X
  1855. X{
  1856. X    critical();
  1857. X    listadd(&TempLists, (addr)l);
  1858. X    non_critical();
  1859. X    return;
  1860. X}
  1861. X
  1862. Xfreetmplists()
  1863. X
  1864. X{
  1865. X    while (TempLists.l_count)
  1866. X        freelist((struct list *) listpop(&TempLists));
  1867. X    return;
  1868. X}
  1869. X
  1870. X#define COLUMNS        80
  1871. X#define SEPDIST        3
  1872. X
  1873. Xchar    *re_comp();
  1874. X
  1875. Xshowlist(l, regexv)
  1876. Xstruct list *l;
  1877. Xaddr *regexv;
  1878. X
  1879. X{
  1880. X    register int i, k;
  1881. X    int tabs, h, j, longest, n;
  1882. X    static struct list matches;
  1883. X    char *errmsg;
  1884. X    register char *cp;
  1885. X
  1886. X    if (l->l_count == 0)
  1887. X        return 0;
  1888. X    longest = 0;
  1889. X    zerolist(&matches);
  1890. X    tmplistadd(&matches);
  1891. X    for (h=0; regexv[h]; h++) {
  1892. X        errmsg = re_comp((char *)regexv[h]);
  1893. X        if (errmsg) {
  1894. X        err(errmsg);
  1895. X        continue;
  1896. X        }
  1897. X        for (i=0; i < l->l_count; i++) {
  1898. X        cp = (char *)l->l_list[i];
  1899. X        if (re_exec(cp) == 0)
  1900. X            continue;
  1901. X        if (instrlist(&matches, cp))
  1902. X            continue;
  1903. X        longest = max(longest, strlen(cp));
  1904. X        strlistadd(&matches, cp);
  1905. X        }
  1906. X    }
  1907. X    n = matches.l_count;
  1908. X    if (n == 0)
  1909. X        return n;
  1910. X        sort_list(&matches, pstrcmp);
  1911. X    tabs = n / ((COLUMNS-1) / (longest + SEPDIST));
  1912. X    tabs += ( n % ((COLUMNS-1) / (longest + SEPDIST)) ? 1 : 0 );
  1913. X    for (j = 1; j <= tabs; j++) {
  1914. X        for (k = j - 1; k < n; k += tabs) {
  1915. X        (void) fputs((char *)matches.l_list[k], stdout);
  1916. X        space(longest - strlen((char *)matches.l_list[k])
  1917. X            + SEPDIST);
  1918. X        }
  1919. X        puts("");
  1920. X    }
  1921. X    return n;
  1922. X}
  1923. X
  1924. Xlistlist(l)
  1925. Xstruct list *l;
  1926. X
  1927. X{
  1928. X    int indx;
  1929. X
  1930. X    for (indx=0; indx < l->l_count; indx++)
  1931. X        (void) printf("%s ", l->l_list[indx]);
  1932. X    puts("");
  1933. X}
  1934. X
  1935. Xlistout(l, fp)
  1936. Xstruct list *l;
  1937. XFILE *fp;
  1938. X
  1939. X{
  1940. X    int i;
  1941. X
  1942. X    for (i=0; i < l->l_count; i++) {
  1943. X        if (i > 0)
  1944. X            fputs(",", fp);
  1945. X        fputs((char *)l->l_list[i], fp);
  1946. X    }
  1947. X    return;
  1948. X}
  1949. @//E*O*F src/lists.c//
  1950. if test 9337 -ne "`wc -c <'src/lists.c'`"; then
  1951.     echo shar: error transmitting "'src/lists.c'" '(should have been 9337 characters)'
  1952. fi
  1953. fi # end of overwriting check
  1954. echo shar: extracting "'src/macros.h'" '(345 characters)'
  1955. if test -f 'src/macros.h' ; then 
  1956.   echo shar: will not over-write existing file "'src/macros.h'"
  1957. else
  1958. sed 's/^X//' >src/macros.h <<'@//E*O*F src/macros.h//'
  1959. X#define    eq(a, b)    !strcmp(((char *)a), ((char *)b))
  1960. X#define    space(n)    { int ii; for(ii=0;ii<n;ii++) fputs(" ", stdout); }
  1961. X#define    decr(a)        (a) = ((a)>0 ? (a)-1 : (a))
  1962. X#define    mask(i)        (1 << (i - 1))
  1963. X#define S(n)        ((n)!=1 ? "s" : "")
  1964. X#define ES(n)        ((n)!=1 ? "es" : "")
  1965. X
  1966. X#define INRANGE(n, f, t) ((f)<(t) ? (f)<=(n)&&(n)<=(t) : (t)<=(n)&&(n)<=(f))
  1967. @//E*O*F src/macros.h//
  1968. if test 345 -ne "`wc -c <'src/macros.h'`"; then
  1969.     echo shar: error transmitting "'src/macros.h'" '(should have been 345 characters)'
  1970. fi
  1971. fi # end of overwriting check
  1972. echo shar: extracting "'src/mem.c'" '(522 characters)'
  1973. if test -f 'src/mem.c' ; then 
  1974.   echo shar: will not over-write existing file "'src/mem.c'"
  1975. else
  1976. sed 's/^X//' >src/mem.c <<'@//E*O*F src/mem.c//'
  1977. X#include "mem.h"
  1978. X
  1979. Xchar    *realloc(), *malloc();
  1980. X
  1981. Xaddr
  1982. XMEM(n)
  1983. Xint n;
  1984. X
  1985. X{
  1986. X    flexaddr m;
  1987. X
  1988. X    critical();
  1989. X    m.p_cp = malloc( (unsigned) n );
  1990. X    if (!m.p_cp)
  1991. X        panic("MEM internal error: out of memory");
  1992. X    non_critical();
  1993. X    return m.p_ap;
  1994. X}
  1995. X
  1996. Xaddr
  1997. XDELTAMEM(p, n)
  1998. Xaddr p;
  1999. Xint n;
  2000. X
  2001. X{
  2002. X    flexaddr m;
  2003. X
  2004. X    critical();
  2005. X    m.p_cp = realloc((char *)p, (unsigned) n);
  2006. X    if (!m.p_cp)
  2007. X        panic("DELTAMEM internal error: out of memory");
  2008. X    non_critical();
  2009. X    return m.p_ap;
  2010. X}
  2011. X
  2012. XFREEMEM(cp)
  2013. Xchar *cp;
  2014. X
  2015. X{
  2016. X    critical();
  2017. X    free((char *) cp);
  2018. X    non_critical();
  2019. X    return;
  2020. X}
  2021. @//E*O*F src/mem.c//
  2022. if test 522 -ne "`wc -c <'src/mem.c'`"; then
  2023.     echo shar: error transmitting "'src/mem.c'" '(should have been 522 characters)'
  2024. fi
  2025. fi # end of overwriting check
  2026. echo shar: extracting "'src/mem.h'" '(544 characters)'
  2027. if test -f 'src/mem.h' ; then 
  2028.   echo shar: will not over-write existing file "'src/mem.h'"
  2029. else
  2030. sed 's/^X//' >src/mem.h <<'@//E*O*F src/mem.h//'
  2031. X#define SHORT_BUF    16
  2032. X#define MEDIUM_BUF    48
  2033. X#define    LONG_BUF    256
  2034. X#define NIL        ((addr)0)
  2035. X#define NOMORE        -1
  2036. X#define    UNDEFINED    -1
  2037. X
  2038. X#define    bcopy(dest, source, n)                \
  2039. X    {                        \
  2040. X        register char *from = (char *)source;    \
  2041. X        register char *to = (char *) dest;    \
  2042. X        register int ii;            \
  2043. X        int nn = n;                \
  2044. X        for (ii=0; ii<nn; ii++)            \
  2045. X            *to++ = *from++;        \
  2046. X    }
  2047. X
  2048. Xtypedef    int         addr_t;
  2049. Xtypedef    addr_t *    addr;    /* general purpose pointer type */
  2050. Xtypedef union {
  2051. X        addr    p_ap;
  2052. X        char    *p_cp;
  2053. X    } flexaddr;        /* to make lint shut UP! */
  2054. X
  2055. Xaddr    MEM(), DELTAMEM();
  2056. @//E*O*F src/mem.h//
  2057. if test 544 -ne "`wc -c <'src/mem.h'`"; then
  2058.     echo shar: error transmitting "'src/mem.h'" '(should have been 544 characters)'
  2059. fi
  2060. fi # end of overwriting check
  2061. echo shar: extracting "'MANIFEST'" '(4939 characters)'
  2062. if test -f 'MANIFEST' ; then 
  2063.   echo shar: will not over-write existing file "'MANIFEST'"
  2064. else
  2065. sed 's/^X//' >MANIFEST <<'@//E*O*F MANIFEST//'
  2066. X  File Name             Kit #   Description
  2067. X-----------------------------------------------------------
  2068. X Copyright                 1
  2069. X Futuribles                1
  2070. X Installation              1
  2071. X MANIFEST                  6   This shipping list
  2072. X Makefile                  1
  2073. X PATCHED                   1
  2074. X README                    1
  2075. X help                      1
  2076. X help/Copyright            1
  2077. X help/Makefile             1
  2078. X help/add-alias.n          1
  2079. X help/add-class.n          1
  2080. X help/add-group.n          1
  2081. X help/add-range.n          1
  2082. X help/add-sig.n            1
  2083. X help/add-to-alias.n       1
  2084. X help/add-to-class.n       1
  2085. X help/add-to-group.n       1
  2086. X help/add-to-sig.n         1
  2087. X help/add-user.n           1
  2088. X help/add-vig.n            1
  2089. X help/alias.n              1
  2090. X help/bind-class.n         1
  2091. X help/bind-group.n         1
  2092. X help/bind-sig.n           1
  2093. X help/checkpoint-changes.n 1
  2094. X help/class.n              1
  2095. X help/cryo.n               1
  2096. X help/deadbeat.n           1
  2097. X help/describe-alias.n     1
  2098. X help/describe-changes.n   1
  2099. X help/describe-class.n     1
  2100. X help/describe-command.n   1
  2101. X help/describe-cryos.n     1
  2102. X help/describe-deadbeats.n 1
  2103. X help/describe-group.n     1
  2104. X help/describe-inactives.n 1
  2105. X help/describe-range.n     1
  2106. X help/describe-sig.n       1
  2107. X help/describe-user.n      1
  2108. X help/disable-user.n       1
  2109. X help/exit-mcp.n           1
  2110. X help/freeze-deadbeats.n   1
  2111. X help/freeze-inactives.n   1
  2112. X help/freeze-user.n        1
  2113. X help/gid.n                1
  2114. X help/inactive.n           1
  2115. X help/list-aliases.n       1
  2116. X help/list-classes.n       1
  2117. X help/list-commands.n      1
  2118. X help/list-cryos.n         1
  2119. X help/list-deadbeats.n     1
  2120. X help/list-groups.n        1
  2121. X help/list-inactives.n     1
  2122. X help/list-ranges.n        1
  2123. X help/list-sigs.n          1
  2124. X help/list-users.n         1
  2125. X help/list-vigs.n          1
  2126. X help/load-file.n          2
  2127. X help/pause-mcp.n          1
  2128. X help/range.n              2
  2129. X help/remove-alias.n       2
  2130. X help/remove-class.n       2
  2131. X help/remove-cryos.n       2
  2132. X help/remove-from-alias.n  2
  2133. X help/remove-from-class.n  2
  2134. X help/remove-from-group.n  2
  2135. X help/remove-from-sig.n    2
  2136. X help/remove-group.n       2
  2137. X help/remove-range.n       2
  2138. X help/remove-sig.n         2
  2139. X help/remove-user.n        2
  2140. X help/remove-vig.n         2
  2141. X help/save-and-exit.n      2
  2142. X help/save-changes.n       2
  2143. X help/shell-escape.n       2
  2144. X help/sig.n                2
  2145. X help/uid.n                2
  2146. X help/unbind-class.n       2
  2147. X help/unbind-group.n       2
  2148. X help/unbind-sig.n         2
  2149. X help/update-alias.n       2
  2150. X help/update-class.n       2
  2151. X help/update-group.n       2
  2152. X help/update-range.n       2
  2153. X help/update-sig.n         2
  2154. X help/update-user.n        2
  2155. X help/vig.n                2
  2156. X help/what-is.n            2
  2157. X man                       1
  2158. X man/Copyright             2
  2159. X man/Makefile              2
  2160. X man/accounts.n            2
  2161. X man/classes.n             2
  2162. X man/mcp.n                 2
  2163. X man/ranges.n              2
  2164. X man/shells.n              2
  2165. X man/sigs.n                3
  2166. X man/vigs.n                3
  2167. X misc                      1
  2168. X misc/freeze               3
  2169. X misc/sorry                3
  2170. X src                       1
  2171. X src/Copyright             3
  2172. X src/Makefile              3
  2173. X src/account.c             3
  2174. X src/account.h             3
  2175. X src/add.c                 3
  2176. X src/alias.c               3
  2177. X src/alias.h               2
  2178. X src/backup.c              3
  2179. X src/bind.c                4
  2180. X src/build.c               4
  2181. X src/ckp.c                 4
  2182. X src/class.c               3
  2183. X src/class.h               3
  2184. X src/command.h             3
  2185. X src/complete.c            5
  2186. X src/date.c                4
  2187. X src/describe.c            5
  2188. X src/disable.c             4
  2189. X src/edit.c                4
  2190. X src/errmsg.c              4
  2191. X src/exists.c              4
  2192. X src/exit.c                4
  2193. X src/exits.c               4
  2194. X src/freeze.c              4
  2195. X src/gpa.c                 6
  2196. X src/gpa.h                 3
  2197. X src/groupmap.c            4
  2198. X src/groupmap.h            4
  2199. X src/history.h             4
  2200. X src/init.c                6
  2201. X src/job.c                 6
  2202. X src/job.h                 4
  2203. X src/lastlog.c             6
  2204. X src/lastlog.h             5
  2205. X src/list.c                6
  2206. X src/lists.c               6
  2207. X src/lists.h               5
  2208. X src/load.c                7
  2209. X src/macros.h              6
  2210. X src/main.c                7
  2211. X src/mem.c                 6
  2212. X src/mem.h                 6
  2213. X src/misc.c                7
  2214. X src/nitpick               7
  2215. X src/pause.c               5
  2216. X src/pwlock.c              7
  2217. X src/range.c               7
  2218. X src/range.h               7
  2219. X src/remove.c              7
  2220. X src/report.c              7
  2221. X src/save.c                8
  2222. X src/save.h                8
  2223. X src/shell.c               8
  2224. X src/sig.c                 8
  2225. X src/sig.h                 8
  2226. X src/signals.c             8
  2227. X src/sort.c                8
  2228. X src/sort.h                8
  2229. X src/sysdep.h              8
  2230. X src/tty.c                 8
  2231. X src/update.c              9
  2232. X src/version.c             8
  2233. X src/yesno.c               8
  2234. @//E*O*F MANIFEST//
  2235. if test 4939 -ne "`wc -c <'MANIFEST'`"; then
  2236.     echo shar: error transmitting "'MANIFEST'" '(should have been 4939 characters)'
  2237. fi
  2238. fi # end of overwriting check
  2239. echo shar: "End of archive 6 (of 8)."
  2240. cp /dev/null ark6isdone
  2241. DONE=true
  2242. for I in 1 2 3 4 5 6 7 8; do
  2243.     if test -! f ark${I}isdone; then
  2244.         echo "You still need to run archive ${I}."
  2245.         DONE=false
  2246.     fi
  2247. done
  2248. case $DONE in
  2249.     true)
  2250.         echo "You have run all 8 archives."
  2251.         echo 'See the README file'
  2252.         ;;
  2253. esac
  2254. ##  End of shell archive.
  2255. exit 0
  2256.